package part1;
/**
 * <p>Title: Project 10 part 1</p>
 * <p>Description: CS 235 Project #10 pt. 1
 *       Shows how to get started with setting up Preconditions and postconditions.</p>
 * 
 * Piece class - represents data associated with a single game piece - server class to Part1
 * 
 * @author Anthony Varghese
 * @date   February 5th 2012
 * @version 1.0
 */

public class Piece {
	/**
	 * State - enumeration type
	 *  - any instance of State can have only the values shown below
	 *  - this is safer than using something like an int to keep track of
	 *  - the "aliveness" of a piece 
	 */
	enum State { alive, dead, zombie } 
	/**
	 * Data members
	 * Class invariants:
	 *  ( (this.getXposition() >= Piece.getMinX()) && (this.getXposition() <= Piece.getMaxX()) )
	 *  ( (this.getYposition() >= Piece.getMinY()) && (this.getYposition() <= Piece.getMaxY()) )
	 */
	private int xposition;
	private int yposition;
	private State state;
	
	// finals
	private static final int MIN_X=0;
	private static final int MIN_Y=0;
	private static final int MAX_X=100;
	private static final int MAX_Y=100;
		
	
	/**
	 * Constructor
	 *  - set the starting position of the Piece object
	 *  
	 * @require (x >= Piece.getMinX()) && (x <= Piece.getMaxX())
	 * @require (y >= Piece.getMinY()) && (y <= Piece.getMaxY())
	 * @ensure ( this.getXposition() == x ) && ( this.getYposition() == y )
	 */
	public Piece(int x, int y){
		setXposition( x );
		setYposition( y );
		state = State.alive;
	}


	/**
	 * compute - returns the y distance if the "hypoteneuse" and the x distance are supplied.
	 * 
	 * @param distance - the hypoteneuse of a right-triangle
	 * @param x        - the length of one leg of the triangle
	 * 
	 * @require 
	 * @ensure  
	 * 
	 * @return a double - the length of the other leg of the triangle 
	 */
	public double compute( double distance, double x) {
		if ( distance <= 0)
			return 0;
		
		double ydist = Math.sqrt( distance * distance - x * x );
		
		return ydist;
	}

	/**
	 * distance - a query method that returns the distance between this piece and some other piece
	 *  
	 * @param s - another Piece
	 * @require other.validPosition()
	 * @ensure  
	 * @return  double value corresponding to the distance between the two pieces
	 */
	public double distance(Piece other) {
		assert ( other != null );
		
		if (this == other)
			return 0;
		
		final int xdist = xposition - other.xposition;
		final int ydist = yposition - other.yposition;
		return Math.sqrt( xdist*xdist + ydist*ydist );
	}

	/**
	 * move  - move this object by amount indicated by parameters
	 * @param i
	 * @param j
	 * @require
	 * @ensure
	 */
	public void move(int i, int j) {
		if (state != State.alive)
			return;

		if ( (xposition+i > MAX_X) || (yposition+j > MAX_Y) ||
			 (xposition+i < MIN_X) || (yposition+j < MIN_Y)   )
			return;
		
		xposition += i;
		yposition += j;
	}


	/**
	 * die - kills this Piece object; i.e. changes its state to "dead"
	 * @require No preconditions
	 * @ensure ( !this.isAlive() )
	 */
	public void die() {
		state = State.dead;
	}
	
	/**
	 * isAlive - reports whether this piece is alive or not
	 * 
	 * @require No preconditions
	 * @ensure  ( this.isAlive() == (this.state==State.alive) )
	 * 
	 * @return a boolean indicating whether this piece is alive
	 */
	public boolean isAlive(){
		return state==State.alive;
	}
	
	/**
	 * isValidPosition - reports whether the position of this piece is valid or not
	 * 
	 * @require No preconditions
	 * @ensure  ( this.isAlive() == (this.state==State.alive) )
	 * 
	 * @return a boolean indicating whether this piece is alive
	 */
	private boolean isValidPosition(){
		return ( xposition >= MIN_X) && (xposition <= MAX_X ) &&
				( yposition >= MIN_Y) && (yposition <= MAX_Y );
	}
	
	// Getters and setters
	
	/**
	 * getXposition
	 *  - used to get the x coordinate of the current position of a Piece object
	 *  
	 * @return an int - the current x postion of this Piece object
	 * @require No preconditions
	 * @ensure ( (this.getXposition() >= Piece.getMinX()) && (this.getXposition() <= Piece.getMaxX()) )
	 */
	public int getXposition() {
		return xposition;
	}

	/**
	 * setXposition
	 *  - used to set the x coordinate of the current position of a Piece object
	 *  
	 * @return
	 * @require (x >= Piece.getMinX()) && (x <= Piece.getMaxX())
	 * @ensure ( this.getXposition() == x )
	 */
	public void setXposition(int x) {
		if (x >= MIN_X && x <= MAX_X)
			xposition = x;
	}
	
	
	/**
	 * getYposition
	 *  - used to get the y coordinate of the current position of a Piece object
	 *  
	 * @return an int - the current y postion of this Piece object
	 * @require No preconditions
	 * @ensure ( (this.getYposition() >= this.getMinY()) && (this.getYposition() <= this.getMaxY()) )
	 */
	public int getYposition() {
		return yposition;
	}

	/**
	 * setYposition
	 *  - used to set the y coordinate of the current position of a Piece object
	 *  
	 * @return
	 * @require (y >= Piece.getMinY()) && (y <= Piece.getMaxY())
	 * @ensure ( this.getYposition() == y )
	 */
	public void setYposition(int y) {
		if (y >= MIN_Y && y <= MAX_Y)
			yposition = y;
	}
	
	/**
	 * getMinX - returns the value of the final, MIN_X
	 * @return int
	 * @require No precondition
	 * @ensure ( this.getMinX() == MIN_X )
	 */
	public static int getMinX() {
		return MIN_X;
	}
	
	/**
	 * getMinY - returns the value of the final, MIN_Y
	 * @return int
	 * @require No precondition
	 * @ensure ( this.getMinY() == MIN_Y )
	 */
	public static int getMinY() {
		return MIN_Y;
	}

	/**
	 * getMaxX - returns the value of the final, MAX_X
	 * @return int
	 * @require No precondition
	 * @ensure ( this.getMaxX() == MAX_X )
	 */
	public static int getMaxX() {
		return MAX_X;
	}

	/**
	 * getMaxY - returns the value of the final, MAX_Y
	 * @return int
	 * @require No precondition
	 * @ensure ( this.getMaxY() == MAX_Y )
	 */
	public static int getMaxY() {
		return MAX_Y;
	}
}
